package org.daochong.lang;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class AbstractContext implements IContext, Serializable {

	private static final long serialVersionUID = 1L;

	protected Map<String, Object> attributes;
	protected Map<String, Object> params;
	protected Map<String, Object> environments;
	protected String id;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public AbstractContext() {
		this.attributes = new LinkedHashMap<String, Object>();
		this.params = new LinkedHashMap<String, Object>();
		this.environments = new LinkedHashMap<String, Object>();
		this.id = this.getClass().getName();
	}

	public void removeAttribute(String id) {
		this.attributes.remove(id);
	}

	public Object getAttribute(String id) {
		return this.attributes.get(id);
	}

	public void setAttribute(String id, Object value) {
		this.attributes.put(id, value);
	}

	public Set<String> getAttributeKeys() {
		return this.attributes.keySet();
	}

	public void clearAttributes() {
		this.attributes.clear();
	}

	public void addAttribute(String id, Object value) {
		Object o = this.attributes.get(id);
		if (o != null) {
			ObjectArrayList list;
			if (o instanceof ObjectArrayList) {
				list = (ObjectArrayList) o;
			} else {
				list = new ObjectArrayList();
				list.add(o);
				this.attributes.put(id, list);
			}
			list.add(value);
		} else {
			this.attributes.put(id, value);
		}
	}

	public void addAttributes(Map<String, Object> attrs) {
		this.attributes.putAll(attrs);
	}

	public void removeParameter(String id) {
		this.params.remove(id);
	}

	public Object getParameter(String id) {
		return this.params.get(id);
	}

	public void setParameter(String id, Object value) {
		this.params.put(id, value);
	}

	public Set<String> getParameterKeys() {
		return this.params.keySet();
	}

	public void clearParameters() {
		this.params.clear();
	}

	@SuppressWarnings("unchecked")
	public void addParameter(String id, Object value) {
		Object o = this.params.get(id);
		if (o != null) {
			List<Object> list;
			if (o instanceof List) {
				list = (List<Object>) o;
			} else {
				list = new ArrayList<Object>();
				list.add(o);
				this.params.put(id, list);
			}
			list.add(value);
		} else {
			this.params.put(id, value);
		}
	}

	public void addParameters(Map<String, Object> params) {
		this.params.putAll(params);
	}

	public Map<String, Object> getAttributes() {
		return this.attributes;
	}

	public Map<String, Object> getParameters() {
		return this.params;
	}

	public Object searchValue(String props) {
		return searchValue(props, null);
	}

	public Object searchValue(String props, Object defaultValue) {
		if (props == null || StringUtils.isEmpty(props)) {
			return defaultValue;
		}
		if (BeanUtil.isParameterKey(props) || props.startsWith("expression:") || BeanUtil.isElKey(props)
				|| BeanUtil.isBeanKey(props)) {
			Object o = BeanUtil.getValue(this, props);
			return o != null ? o : defaultValue;
		} else {
			return props;
		}
	}

	public void setBean(String name, Object object) {

	}

	public Object getBean(String name) {
		return null;
	}

	public <T> T getBean(Class<T> clazz) {
		return null;
	}

	
	public Object expression(String expression) {
		return getExpressionProvider().eval(expression, this);
	}

	
	public boolean expressionCondition(String expression) {
		Object o = expression(expression);
		if (o == null)
			return false;
		if (o instanceof Boolean)
			return ((Boolean) o);
		String str = o.toString();
		if ("true".equalsIgnoreCase(str) && "T".equalsIgnoreCase(str)) {
			return true;
		}
		try {
			return Double.parseDouble(str) > 0;
		} catch (Throwable e) {
			return false;
		}
	}

	public Expression getExpressionProvider() {
		Expression ep = null;
		try {
			ep = this.getBean(Expression.class);
		} catch (Throwable e) {

		}
		if (ep == null) {
			ep = ExpressionFactory.getDefault();
		}
		return ep;
	}

	
	public void removeEnvironment(String id) {
		this.environments.remove(id);
	}

	
	public Object getEnvironment(String id) {
		return this.environments.get(id);
	}

	
	public void setEnvironment(String id, Object value) {
		this.environments.put(id, value);
	}

	
	public Set<String> getEnvironmentKeys() {
		return this.environments.keySet();
	}

	
	public void clearEnvironments() {
		this.environments.clear();
	}

	
	public void addEnvironment(String id, Object value) {
		Object o = this.environments.get(id);
		if (o != null) {
			ObjectArrayList list;
			if (o instanceof ObjectArrayList) {
				list = (ObjectArrayList) o;
			} else {
				list = new ObjectArrayList();
				list.add(o);
				this.environments.put(id, list);
			}
			list.add(value);
		} else {
			this.environments.put(id, value);
		}
	}

	
	public void addEnvironments(Map<String, Object> attrs) {
		this.environments.putAll(attrs);
	}

	
	public Map<String, Object> getEnvironments() {
		return this.environments;
	}

}
